﻿'***********************************************************************
' Assembly         : SOFA.Caching
' Copyright        : (c) Jebarson. All rights reserved.
' Website           : http://www.jebarson.info
'***********************************************************************
Option Strict Off

Namespace Caching
    ''' <summary>
    ''' Factory for cache storage.
    ''' </summary>
    ''' <typeparam name="T">The cache config. Pass the config as per the cache type.</typeparam>
    Friend NotInheritable Class CacheStorageFactory(Of T As ICacheStorageConfig)

#Region " Constructors "
        ''' <summary>
        ''' Initializes a new instance of the <see cref="CacheStorageFactory(Of T)" /> class.
        ''' </summary>
        ''' <param name="storageConfig">The storage config.</param>
        Public Sub New(ByVal storageConfig As T)

            Me.storageConfigValue = storageConfig
        End Sub
#End Region

#Region " Declarations "
        ''' <summary>
        ''' Member variable for storage config.
        ''' </summary>
        Private storageConfigValue As T
#End Region

#Region " Public Properties "
        ''' <summary>
        ''' Gets the storage config.
        ''' </summary>
        ''' <value>The storage config.</value>
        Public ReadOnly Property StorageConfig() As T
            Get
                Return Me.storageConfigValue
            End Get
        End Property
#End Region

#Region " Shared Methods "
        ''' <summary>
        ''' Initializes the storage item entry.
        ''' </summary>
        ''' <param name="itemEntry">The item entry.</param>
        ''' <param name="storageConfig">The storage config.</param>
        Public Shared Sub InitializeStorageItemEntry(ByRef itemEntry As Object, ByVal storageConfig As ICacheStorageConfig)

            With itemEntry
                .Priority = storageConfig.DefaultCachePriority
                .LastAccessedTime = DateTime.Now
                .ExpiryTime = .LastAccessedTime.Add(storageConfig.RefreshTime)
            End With
        End Sub
#End Region

#Region " Public Methods "
        ''' <summary>
        ''' Sets the storage item.
        ''' </summary>
        ''' <param name="item">The item.</param>
        ''' <param name="enforceLoad">if set to <c>true</c> [enforce load].</param>
        Public Sub SetStorageItem(ByRef item As Object, Optional ByVal enforceLoad As Boolean = False)
            Dim storageItem As Object ' StorageItem(Of StorageItemEntry)
            Dim cachedItem As Object ' StorageItem(Of StorageItemEntry)

            storageItem = item
            cachedItem = Me.StorageConfig.Storage.GetStorageItem(storageItem.Name)

            If cachedItem Is Nothing Then
                Me.LoadStorageItem(storageItem)
                Me.StorageConfig.Storage.AddStorageItem(storageItem)
            ElseIf enforceLoad Then
                ' Reload the cached item.
                Me.LoadStorageItem(cachedItem)
            Else
                With storageItem
                    .StorageDictionary = cachedItem.StorageDictionary
                    .IndexList = cachedItem.IndexList
                End With
            End If
        End Sub

        ''' <summary>
        ''' Loads the storage item.
        ''' </summary>
        ''' <param name="storageItem">The storage item.</param>
        Private Sub LoadStorageItem(ByVal storageItem As Object)
            Dim itemEntry As Object

            SyncLock storageItem
                With (storageItem)
                    .StorageDictionary = New Dictionary(Of String, StorageItemEntry)
                    .IndexList = New List(Of String)

                    For Each row As DataRow In .LoadAll()
                        itemEntry = .CreateChildInstance()
                        InitializeStorageItemEntry(itemEntry, Me.StorageConfig)
                        .Add(ObjectManager.Instance.LoadObject(Of StorageItemEntry)(row, itemEntry))
                        itemEntry.Data = itemEntry
                    Next
                End With
            End SyncLock

        End Sub
#End Region

    End Class
End Namespace